package com.wstuo.common.priorityMatrix.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.dictionary.dao.IDataDictionaryItemsDAO;
import com.wstuo.common.config.dictionary.dto.DataDictionaryItemsDTO;
import com.wstuo.common.config.dictionary.service.IDataDictionaryItemsService;
import com.wstuo.common.priorityMatrix.dao.IPriorityMatrixDAO;
import com.wstuo.common.priorityMatrix.dto.PriorityMatrixDTO;
import com.wstuo.common.priorityMatrix.dto.PriorityMatrixDataShowDTO;
import com.wstuo.common.priorityMatrix.dto.PriorityMatrixGridDTO;
import com.wstuo.common.priorityMatrix.entity.PriorityMatrix;
import com.wstuo.common.rules.dao.IRuleDAO;
import com.wstuo.common.rules.dao.IRulePackageDAO;
import com.wstuo.common.rules.entity.Rule;
import com.wstuo.common.rules.entity.RuleAction;
import com.wstuo.common.rules.entity.RuleConstraint;
import com.wstuo.common.rules.entity.RulePackage;
import com.wstuo.common.rules.entity.RulePattern;
import com.wstuo.common.rules.parser.ProcreationDrlFiles;

/**
 * 优先级矩阵Service类
 * @author WSTUO
 *
 */
public class PriorityMatrixService implements IPriorityMatrixService {
	@Autowired
	private IPriorityMatrixDAO priorityMatrixDAO;
	@Autowired
	private IDataDictionaryItemsDAO dataDictionaryItemsDAO;
	@Autowired
	private IDataDictionaryItemsService dataDictionaryItemsService;
	@Autowired
    private IRulePackageDAO rulePackageDAO;
	@Autowired
	private IRuleDAO ruleDAO;
	
	private ProcreationDrlFiles procreationDrlFiles=new ProcreationDrlFiles();
	
	
	
	
	
	/**
	 * 创建所有优先级规则.
	 */
	private void syncPrionityRules(){
		
		RulePackage rulePackage=rulePackageDAO.findUniqueBy("packageName", RulePackage.PRIORITYMATRIX);

		if(rulePackage==null){//未实例化，创建一个新的包
			
			rulePackage=new RulePackage();
			rulePackage.setPackageName(RulePackage.PRIORITYMATRIX);
			rulePackage.setImports("com.wstuo.itsm.request.dto.RequestDTO;");
			rulePackage.setLocation("prioritymatrix-rule.drl");
			rulePackage=rulePackageDAO.merge(rulePackage);
		}

		
		List<PriorityMatrix> priorityMatrixs=priorityMatrixDAO.findAll();
		List<Rule> rules=new ArrayList<Rule>(priorityMatrixs.size());
		
		for(PriorityMatrix p:priorityMatrixs){
			if(p.getAffect()!=null && p.getUrgency()!=null && p.getPriority()!=null){
				String ruleName = "prioritymatrix-"+p.getAffect().getDcode()+"-"+p.getUrgency().getDcode();
				Rule rule=ruleDAO.findUniqueBy("ruleName", ruleName);
				if(rule==null){
					rule = new Rule();
				}
				rule.setDialect("mvel");
				rule.setRuleName(ruleName);
				
				//条件
				RulePattern rp=new RulePattern();
				rp.setPatternType("RequestDTO");
				rp.setPatternBinding("dto");
				
				List<RuleConstraint> ruleConstraints=new ArrayList<RuleConstraint>(2);
				
				RuleConstraint c1=new RuleConstraint();
				
				c1.setSequence(1);
				c1.setAndOr("and");
				c1.setDataType("Long");
				c1.setPattern(rp);
				c1.setPropertyName("effectRangeNo ==");
				c1.setPropertyValue(p.getAffect().getDcode().toString());
				ruleConstraints.add(c1);
				
				RuleConstraint c2=new RuleConstraint();
				c2.setSequence(2);
				c2.setAndOr("and");
				c2.setDataType("Long");
				c2.setPattern(rp);
				c2.setPropertyName("seriousnessNo ==");
				c2.setPropertyValue(p.getUrgency().getDcode().toString());
				ruleConstraints.add(c2);
				
				rp.setConstraints(ruleConstraints);
				rule.setCondition(rp);
				
				//动作
				List<RuleAction> actions=new ArrayList<RuleAction>(1);
				RuleAction ac1=new RuleAction();
				ac1.setSequence(0);
				ac1.setAndOr("and");
				ac1.setDataType("Long");
				ac1.setPropertyName("priorityNo");
				ac1.setGivenName("priorityNo");
				ac1.setGivenValue(p.getPriority().getDcode().toString());
				actions.add(ac1);
				
				rule.setActions(actions);
				
				rules.add(rule);
			
			}
			
		 }
		
		rulePackage.setRules(rules);
		rulePackageDAO.merge(rulePackage);
		
		//打印规则
		procreationDrlFiles.printDrlFiles(rulePackage);
		
		
		
	}
	
	
	
	
	
	
	/**
	 * 保存优先级矩阵
	 * @param dto
	 */
	@Transactional
	public void savePriorityMatrix(PriorityMatrixDTO dto){
		PriorityMatrix entity=priorityMatrixDAO.findPriorityMatrixByUrgencyAffect(dto);
		if(dto!=null){
			if(dto.getAffectId()!=null){
				entity.setAffect(dataDictionaryItemsDAO.findById(dto.getAffectId()));
			}
			if(dto.getUrgencyId()!=null){
				entity.setUrgency(dataDictionaryItemsDAO.findById(dto.getUrgencyId()));
			}
			if(dto.getPriorityId()!=null){
				entity.setPriority(dataDictionaryItemsDAO.findById(dto.getPriorityId()));
			}else{
				entity.setPriority(null);
			}
		}
		priorityMatrixDAO.merge(entity);
		
		syncPrionityRules();
		dto.setPriorityMatrixId(entity.getId());
		
	}
	/**
	 * 获取优先级矩阵显示数据
	 * @return 返回优先级矩阵前台显示数据 PriorityMatrixDataShowDTO
	 */
	@Transactional
	public PriorityMatrixDataShowDTO findPriorityMatrixDataShow(){
		PriorityMatrixDataShowDTO dto=new PriorityMatrixDataShowDTO();
		//紧急度
		List<DataDictionaryItemsDTO> urgencyDTO=dataDictionaryItemsService.findDictionaryItemByGroupCode("seriousness");
		//影响范围
		List<DataDictionaryItemsDTO> affectDTO=dataDictionaryItemsService.findDictionaryItemByGroupCode("effectRange");
		
		//优先级
		List<PriorityMatrix> priority=priorityMatrixDAO.findAll();
		List<PriorityMatrixGridDTO> priorityDTO=new ArrayList<PriorityMatrixGridDTO>();
		for(PriorityMatrix entity:priority){
			PriorityMatrixGridDTO priorityDto=new PriorityMatrixGridDTO();
			if(entity.getAffect()!=null){
				priorityDto.setAffectId(entity.getAffect().getDcode());
				priorityDto.setAffectName(entity.getAffect().getDname());
			}
			
			if(entity.getUrgency()!=null){
				priorityDto.setUrgencyId(entity.getUrgency().getDcode());
				priorityDto.setUrgencyName(entity.getUrgency().getDname());
			}
			
			if(entity.getPriority()!=null){
				priorityDto.setPriorityId(entity.getPriority().getDcode());
				priorityDto.setPriorityName(entity.getPriority().getDname());
			}
			
			priorityDTO.add(priorityDto);
		}
		dto.setAffect(affectDTO);
		dto.setUrgency(urgencyDTO);
		dto.setPriority(priorityDTO);
		return dto;
	}
	
}
